#include <functional>
#include <iostream>
using std::cout;
using std::endl;
using std::function;

//一切皆对象的观点 => std::function  统筹所有的函数形式

//add是一个对象, 他的类型是什么?
//
//函数类型由返回值+形参列表共同决定
int add(int x, int y)
{
    cout << "int add(int,int)" << endl;
    return x + y;
}

//multiply是一个对象
int multiply(int x, int y)
{
    cout << "int multiply(int,int)" << endl;
    return x * y;
}

struct Foo
{
    int add(int x, int y)
    {   
        cout << "int Foo::add(int,int)" << endl;
        return x + y;   
    } 

    int multiply(int x, int y)
    {
        cout << "int Foo::multiply(int,int)" << endl;
        return x * y;
    }
};


//函数也是一种类型
typedef int(*Function)(int,int);//函数指针
typedef int(Foo::*MemFunc)(int,int);//成员函数指针

void test2()
{
    int a = 3, b = 4;
    function<int(int,int)> f1;

    f1 = add;
    cout << f1(a, b) << endl;

    f1 = multiply;
    cout << f1(a, b) << endl;

    int (*func)(int,int) = add;
    f1 = func;
    cout << f1(a, b) << endl;

    //Foo::add函数是有三个参数
    //因此需要提前绑定一个参数this指针
    Foo foo;
    //占位符本质就是一个变量
    using namespace std::placeholders;
    f1 = std::bind(&Foo::add, foo, _1, _2);
    cout << f1(a, b) << endl;
}

void test0()
{
    int a = 3, b = 2;
    cout << "add(a, b):" << add(a, b) << endl;

    //int * p;
    //int(int,int) * func = add;
    int (*func)(int,int) = add;
    cout << "func(a, b):" << func(a, b) << endl;

    func = multiply;
    cout << "func(a, b):" << func(a, b) << endl;
}

void test1()
{
    int a = 3, b = 2;
    Function func = &add;
    cout << "func(a, b):" << func(a, b) << endl;

    func = multiply;
    cout << "func(a, b):" << func(a, b) << endl;

    Foo foo;
    Foo * pfoo = nullptr;
    MemFunc  memfunc = &Foo::add;//非静态成员函数，加上&取地址符号
    //对于成员函数指针的调用，要借助于对象来完成
    //memfunc(a, b);
    cout << (foo.*memfunc)(a, b) << endl;
    cout << (pfoo->*memfunc)(a, b) << endl;
}



int main()
{
    /* test0(); */
    /* test1(); */
    test2();
    return 0;
}

